from typing import Union, Annotated

from fastapi import APIRouter, Form, File, UploadFile, HTTPException, Request
from pydantic import BaseModel

from error import UnicornException

router = APIRouter()


@router.post("/form/login_1/", tags=["表单请求"])
async def login_1(username: str = Form(), password: str = Form()):
    return {"username": username, "password": password}


class FormData(BaseModel):
    username: str
    password: str


@router.post("/form/login_2/", tags=["表单请求"])
async def login_2(data: Annotated[FormData, Form()]):
    return data


class FormData2(BaseModel):
    model_config = {"extra": "forbid"}
    username: str
    password: str


@router.post("/form/login_2_1/", tags=["表单请求"])
async def login_2_1(data: Annotated[FormData, Form()]):
    return data


# File 小文件 ，把文件的所有内容都存储在内存里；
# UploadFile（通用），大文件，存储在内存的文件超出最大上限时，FastAPI 会把文件存入磁盘；
@router.post("/form/files_3/", tags=["表单请求"])
async def create_file_3(file: bytes = File()):
    return {"file_size": len(file)}


@router.post("/form/uploadfile_4/", tags=["表单请求"])
async def create_upload_file_4(file: UploadFile):
    return {"filename": file.filename, "content_type": file.content_type, "file": file.file}


@router.post("/form/uploadfile_5/", tags=["表单请求"])
async def create_upload_file_5(file: Union[UploadFile, None] = File(default=None, description="上传文件")):
    if not file:
        return {"message": "No upload file sent"}
    else:
        return {"filename": file.filename}


# 多文件上传
@router.post("/form/uploadfiles_6", tags=["表单请求"])
async def create_upload_files_6(files: list[UploadFile]):
    return {"filenames": [file.filename for file in files]}


@router.post("/form/form_files_7/", tags=["表单请求"])
async def create_file_7(file: bytes = File(), fileb: UploadFile = File(), token: str = Form()):
    return {
        "file_size": len(file),
        "token": token,
        "fileb_content_type": fileb.content_type,
    }


error_items = {"foo": "The Foo Wrestlers"}


# 自定义错误响应头headers
@router.get("/form/error_8/{item_id}", tags=["表单请求"], description="获取错误信息")
async def read_item_8(item_id: str):
    if item_id not in error_items:
        raise HTTPException(status_code=405, detail="Item not found", headers={"X-Error": "There goes my error"}, )
    return {"item": error_items[item_id]}


@router.get("/form/unicorns_9/{name}", tags=["表单请求"], description="获取自定义错误信息")
async def read_unicorn_9(name: str):
    if name == "yolo":
        raise UnicornException(name=name)
    return {"unicorn_name": name}
